package com.alit.face.koala.service.face.baidu;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;

import org.apache.commons.codec.binary.Base64;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.alit.face.koala.app.data.KoalaEmpLoyeeRequest;
import com.alit.face.koala.entity.BaiduFaceDetecteResult;
import com.alit.face.koala.entity.KoalaEmpLoyeeEntity;
import com.alit.face.koala.projectvariable.PVK;
import com.alit.face.koala.repository.BaiduFaceDetecteResultRepository;
import com.baidu.aip.face.AipFace;
import com.baidu.aip.face.MatchRequest;
import com.litong.utils.projectvariable.PVU;

import lombok.extern.slf4j.Slf4j;

/**
 * 百度人脸识别服务
 * @author litong
 */
@Service
@Slf4j
public class BaiduFaceService {
  @Autowired
  private BaiduFaceDetecteResultRepository baiduFaceDetecteResultRepository;

  private AipFace client;

  private AipFace getAipClient() {
    if (client == null) {
      String aid = PVU.getValue(PVK.baiduFaceAid);
      String ak = PVU.getValue(PVK.baiduFaceAk);
      String as = PVU.getValue(PVK.baiduFaceAs);
      client = new AipFace(aid, ak, as);
      // 可选：设置网络连接参数
      client.setConnectionTimeoutInMillis(2000);
      client.setSocketTimeoutInMillis(60000);
      // 可选：设置代理服务器地址, http和socket二选一，或者均不设置
      // client.setHttpProxy("proxy_host", proxy_port); // 设置http代理
      // client.setSocketProxy("proxy_host", proxy_port); // 设置socket代理
      // 查询组列表,获取accessToken,连接百度
      JSONObject groupList = client.getGroupList(null);
      log.info("查询组列表:" + groupList);
    }
    return client;
  }

  public BaiduFaceService() {
    // 连接百度
    client = getAipClient();
    log.info("连接百度成功:" + client);
  }

  /**
   * 百度人脸检测 
   */
  public JSONObject detected(String encodeBase64String) {
    // 初始化一个AipFace
    client = getAipClient();

    // 调用接口
    String imageType = "BASE64";

    // 传入可选参数调用接口
    HashMap<String, String> options = new HashMap<String, String>();
    options.put("face_field", "age,gender");
    options.put("max_face_num", "2");
    options.put("face_type", "LIVE");
    options.put("liveness_control", "LOW");

    // 人脸检测
    JSONObject res = client.detect(encodeBase64String, imageType, options);

    return res;
  }

  /**
   * 人脸搜索
   */
  public JSONObject search(String image, String imageType, String groupIdList) {
    client = getAipClient();
    HashMap<String, String> options = new HashMap<String, String>();
    // 匹配阈值
    options.put("match_threshold", "90");
    JSONObject res = client.search(image, imageType, groupIdList, options);
    return res;
  }

  /**
   * 人脸注册
   */
  public JSONObject add(String image, String imageType, String groupId, String userId,
      HashMap<String, String> options) {
    client = getAipClient();
    // 人脸注册
    JSONObject res = client.addUser(image, imageType, groupId, userId, options);
    return res;
  }

  private JSONObject update(String image, String imageType, String groupId, String userId,
      HashMap<String, String> options) {
    client = getAipClient();
    JSONObject res = client.updateUser(image, imageType, groupId, userId, options);
    return res;
  }

  public void addUser(KoalaEmpLoyeeRequest employee, KoalaEmpLoyeeEntity entity) {
    // 保存用户到百度库
    String imageType = "FACE_TOKEN";
    String groupId = entity.getBaiduGroupId();
    HashMap<String, String> options = new HashMap<>(1);
    options.put("user_info", JSON.toJSONString(entity));
    String userId = entity.getId() + "";
    List<String> photoIds = employee.getPhotoIds();
    for (String md5 : photoIds) {
      String image = getFaceToken(md5);
      add(image, imageType, groupId, userId, options);
    }
  }

  /**
   * 删除用户
   */
  public JSONObject deleteById(String id, String baiduGroupId) {
    client = getAipClient();
    // 人脸注册
    JSONObject res = client.deleteUser(baiduGroupId, id, null);
    return res;
  }

  public void update(KoalaEmpLoyeeRequest employee, KoalaEmpLoyeeEntity entity) {
    // 保存用户到百度库
    String imageType = "FACE_TOKEN";
    String groupId = entity.getBaiduGroupId();
    HashMap<String, String> options = new HashMap<>(1);
    options.put("user_info", JSON.toJSONString(entity));
    String userId = entity.getId() + "";
    List<String> photoIds = employee.getPhotoIds();
    for (String md5 : photoIds) {
      String image = getFaceToken(md5);
      update(image, imageType, groupId, userId, options);
    }
  }

  public String getFaceToken(String md5) {
    Optional<BaiduFaceDetecteResult> optional = baiduFaceDetecteResultRepository.findById(md5);
    String result = optional.get().getResult();
    org.json.JSONObject jsonObject = null;
    try {
      jsonObject = new org.json.JSONObject(result);
    } catch (JSONException e1) {
      e1.printStackTrace();
    }
    String image = null;
    try {
      image = jsonObject.getJSONObject("result").getJSONArray("face_list").getJSONObject(0).getString("face_token");
    } catch (JSONException e) {
      e.printStackTrace();
    }
    return image;
  }

  public JSONObject match(String image1, String image2) {
    client = getAipClient();
    // image1/image2也可以为url或facetoken, 相应的imageType参数需要与之对应。
    MatchRequest req1 = new MatchRequest(image1, "BASE64");
    MatchRequest req2 = new MatchRequest(image2, "BASE64");
    ArrayList<MatchRequest> requests = new ArrayList<MatchRequest>();
    requests.add(req1);
    requests.add(req2);
    JSONObject res = client.match(requests);
    return res;
  }

  public String match(MultipartFile file1, MultipartFile file2) {
    String image1 = null;
    String image2 = null;
    try {
      image1 = Base64.encodeBase64String(file1.getBytes());
      image2 = Base64.encodeBase64String(file2.getBytes());
    } catch (IOException e) {
      e.printStackTrace();
    }
    JSONObject match = match(image1, image2);
    return match.toString();
  }

  public JSONObject matchFaceTotenImage(String faceToken, String image2) {
    client = getAipClient();
    // image1/image2也可以为url或facetoken, 相应的imageType参数需要与之对应。
    MatchRequest req1 = new MatchRequest(faceToken, "FACE_TOKEN");
    MatchRequest req2 = new MatchRequest(image2, "BASE64");
    ArrayList<MatchRequest> requests = new ArrayList<MatchRequest>();
    requests.add(req1);
    requests.add(req2);
    JSONObject res = client.match(requests);
    return res;
  }
}
